package gecko;

/**
 * 类似MQTT的Topic匹配方式
 *
 * @author 陈哈哈 (yoojiachen@gmail.com, chenyongjia@parkingwang.com)
 * @version 0.1
 */
public class Topic {

    public final String topic;
    private final Level[] mLevels;

    private Topic(String topic) {
        this.topic = topic;
        final String[] ss = topic.split("/");
        this.mLevels = new Level[ss.length];
        for (int i = 0; i < ss.length; i++) {
            mLevels[i] = new Level(ss[i]);
        }
    }

    /**
     * 判断当前Topic与外部Topic是否匹配
     *
     * @param topic 外部Topic
     * @return 是否匹配
     */
    public boolean matches(String topic) {
        // /gecko/devices/001/update
        // /gecko/+/+/#
        final String[] ss = topic.split("/");
        if (mLevels.length > ss.length) {
            return false;
        }
        for (int i = 0; i < mLevels.length; i++) {
            final Level me = mLevels[i];
            if (me.matchAll) {
                return true;
            } else if (!me.matches(ss[i])) {
                return false;
            }
        }
        return true;
    }

    public static Topic create(String topic) {
        return new Topic(topic);
    }

    ////

    private static class Level {

        final String level;
        final boolean matchAll;

        Level(String level) {
            this.level = level;
            matchAll = "#".equals(level);
        }

        boolean matches(String key) {
            switch (this.level) {
                case "+":
                    return true;
                case "#":
                    return true;
                default:
                    return this.level.equals(key);
            }
        }

    }
}
